/**      
 * @file		typeDefBike.cpp
 * @description		Demonstrates the use of the keyword typedef
 *			Typedef simplifies the pass by reference of 
 *			a bike pointer. Here we give a Bike pointer
 *			data type a new name, "BikePtr".
 *			You will need the following files for this to work:
 *				Bike.h
 *				Bike.cpp
 * @course		CSCI 123 Section 00000
 * @assignment 
 * @date		mm/dd/yyyy
 * @author		Brad Rippe (00000000) brippe@fullcoll.edu
 * @version		1.0
 */
#include <iostream>
#include "Bike.h"
using namespace std;

// typedef is a keyword used to give
// a data type a new name
typedef Bike* BikePtr;

/**
 * This outputs the name and size of the bike
 * @param aBikePtr a pointer to a bike. This pointer
 *		is passed by reference. What is really
 *		happening here? We are not copying the pointer
 *		and putting it on the function stack. This 
 *		eliminates the overhead of the copy.
 *		The typedef simplifies the function signature from
 *		void outputBike(Bike*& aBikePtr) to
 *		void outputBike(BikePtr& aBikePtr)
 */
void outputBike(const BikePtr& aBikePtr);

/**
 * @return zero if the application executes successfully
 */
int main() {
	// calls the bike's 
	// three parameter constructor
	BikePtr myBike = new Bike("My Bike", 17, 26.0);
	outputBike(myBike);
	
	cout << "deleting myBike\n\n";
	// returns memory allocated for a bike to the free store
	// here we clean up after ourselves
	delete myBike;

	// calls the bike's 
	// default constructor
	BikePtr mySecondBike = new Bike;
	outputBike(mySecondBike);
	
	cout << "deleting mySecondBike\n";
	// returns memory allocated for a bike to the free store
	delete mySecondBike;

	return 0;
}

void outputBike(const BikePtr& aBikePtr) {
	cout << "Bike Name: " << aBikePtr->getName() << endl;

	// this operator dereferences the ptr and accesses the member function
	// all with one operator ->
	// this is the operator we usually use
	cout << "Bike size: " << aBikePtr->getSize() << endl;
}
